home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / threads / ThreadsUIOMMap.c < prev    next >
C/C++ Source or Header  |  1991-09-10  |  18KB  |  794 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA 94304
  14.   endcopyright */
  15.  
  16. /*
  17.  * ThreadsUIOMMap.c
  18.  *
  19.  * Demers, November 12, 1990 2:35:23 pm PST
  20.  * Boehm, August 16, 1991 10:47:45 am PDT
  21.  *
  22.  * Unix MMap simulation (mapped files, frame buffers, etc),
  23.  *   for Xerox Runtime threads package.
  24.  */
  25.  
  26. #include "xr/Threads.h"
  27. #include "xr/ThreadsBackdoor.h"
  28. #include "xr/ThreadsSharedMem.h"
  29. #include "xr/ThreadsMsgPrivate.h"
  30. #include "xr/UIO.h"
  31. #include "xr/UIOPrivate.h"
  32. #include "xr/Errno.h"
  33. #include "xr/ThreadsSchedCtl.h"
  34.  
  35.  
  36. /*
  37.  * UNIX (SunOS 4.0) dependent memory management ...
  38.  */
  39.  
  40. #include <sys/types.h>
  41. #include <sys/file.h>
  42. #include <sys/mman.h>
  43.  
  44. /*
  45.  * includes for sending descriptors
  46.  */
  47.  
  48. #include <sys/uio.h>
  49. #include <sys/socket.h>
  50.  
  51.  
  52. #define DEBUG_MMAP 0
  53.  
  54.  
  55. /*
  56.  * MMap / MUnmap / MProtect / MCtl
  57.  */
  58.  
  59.  
  60. typedef struct XR_MMArgsRep {
  61.     XR_Pointer mma_addr;
  62.     unsigned mma_len;
  63.     int mma_prot;
  64.     int mma_flags;
  65.     int mma_fd;
  66.     unsigned mma_off;
  67.     bool mma_include_iops;   /* Apply Mprotect to IOPs.  Assumed true */
  68.                      /* for MMap / MUnmap.              */
  69.     int mma_results[XR_MAX_VPS+XR_MAX_IOPS];
  70. } * XR_MMArgs;
  71.  
  72.  
  73. /* where to put a result ... */
  74.  
  75. #define ResultIndex() ((XR_vpe != NIL) \
  76.             ? XR_vpe->vpe_index \
  77.             : XR_MAX_VPS + XR_iope->iope_index )
  78.  
  79.  
  80. /* VP order issuer (runs in IOP) */
  81.  
  82. static int /* -errno */
  83. XR_MemIOPIssueVPOrder (mma, proc)
  84.     XR_MMArgs mma;
  85.     void (*proc)(/* XR_VPOrder vpo */);
  86. {
  87.     int i, ans;
  88.  
  89.     XR_iope->iope_vpOrderBuf.vpo_mma = ((unsigned)(mma));
  90.     XR_IssueVPOrder(
  91.         /*order*/    &(XR_iope->iope_vpOrderBuf),
  92.         /*proc*/    proc,
  93.         /*stop*/    FALSE
  94.     );
  95.     for( i = 0; i < XR_maxVPs; i++ ) {
  96.         if( (ans = mma->mma_results[i]) != 0 ) return ans;
  97.     }
  98.     return 0;
  99. }
  100.  
  101.  
  102.  
  103.  
  104. /* mmap primitives */
  105.  
  106. static bool
  107. XR_ValidAddressRangeForMMap(addr, len)
  108.     XR_Pointer addr;
  109.     unsigned len;
  110. {
  111.     XR_Pointer limit;
  112.  
  113.     if( addr != XR_ComputeAddress(addr, 0, XR_ROUND_DOWN) ) {
  114.         /* not page-aligned */
  115.         return FALSE;
  116.     }
  117.  
  118. #ifdef UNDEFINED
  119.     limit = XR_sysArea->sa_heapLimit;
  120.     if( (limit == 0) /* heap limit not yet set */
  121.             || (addr < limit) /* heap might grow to here */ ) {
  122. #       ifdef UNDEFINED
  123.             /* can't do this check yet, because some old code still
  124.                calls mmap inside a pointerfree_new'd object, but ... */
  125.             return FALSE;
  126. #       else
  127.             XR_ConsoleMsg(
  128.                 "%? ValidAddressRangeForMMap addr 0x%x len %d lim 0x%x\n",
  129.                 addr, len, limit );
  130. #       endif
  131.     }
  132. #endif
  133.  
  134.     return TRUE;
  135. }
  136.  
  137.  
  138. static int /* -errno */
  139. XR_DoMMapProc (mma, fd)
  140.     XR_MMArgs mma;
  141.     int fd;    /* if >= 0, overrides mma->mma_fd */
  142. {
  143.     XR_Pointer mmapAns;
  144.     int theResult = 0;
  145.  
  146. #if DEBUG_MMAP
  147.     XR_ConsoleMsg("MMapVPOrder addr 0x%x len %d prot 0x%x flags 0x%x\n",
  148.         mma->mma_addr, mma->mma_len, mma->mma_prot, mma->mma_flags);
  149.     XR_ConsoleMsg(" ... mma_fd %d fd %d off 0x%x\n",
  150.         mma->mma_fd, fd, mma->mma_off);
  151. #endif
  152.  
  153.     if( fd < 0 ) fd = mma->mma_fd;
  154.     mmapAns = (XR_Pointer) mmap(
  155.         mma->mma_addr,
  156.         mma->mma_len,
  157.         mma->mma_prot,
  158.         mma->mma_flags,
  159.         fd,
  160.         mma->mma_off
  161.     );
  162.     if( mmapAns != mma->mma_addr ) {
  163.         theResult = -errno;
  164. #       if DEBUG_MMAP
  165.             XR_ConsoleMsg("%? DoMMapProc mmap ans 0x%x errno %d\n",
  166.                 mmapAns, -theResult);
  167.             XR_ConsoleMsg(
  168.                 "addr 0x%x len %d prot 0x%x flags 0x%x fd %d off %d\n",
  169.                 mma->mma_addr, mma->mma_len, mma->mma_prot, mma->mma_flags,
  170.                 fd, mma->mma_off);
  171. #       endif
  172.     }
  173.     mma->mma_results[ResultIndex()] = theResult;
  174.     return theResult;
  175. }
  176.  
  177.  
  178.  
  179. /* MMap VP Procs */
  180.  
  181.  
  182. void
  183. XR_MMapVPOrderProc (vpo)
  184.     XR_VPOrder vpo;
  185. {
  186.     XR_MMArgs mma = (XR_MMArgs)(vpo->vpo_mma);
  187.  
  188.     if( XR_vpe == NIL )
  189.         XR_Panic("MMapVPOrderProc 0");
  190.     (void) XR_DoMMapProc(mma, (-1));
  191. }
  192.  
  193.  
  194. /* MMap IOP Procs */
  195.  
  196.  
  197. static int /* fd or -errno */
  198. XR_MMapIOPRecvDescriptor ()
  199. {
  200.     struct iovec iov[1];
  201.     int fd;
  202.     struct msghdr h;
  203.     int ans;
  204.     int buf;    /* Dummy to circumvent recvmsg bug */
  205.     
  206.     fd = (-1);
  207.     h.msg_name = NIL;
  208.     h.msg_namelen = 0;
  209.     iov[0].iov_base = (caddr_t)(&buf);
  210.     iov[0].iov_len = sizeof (int);
  211.     h.msg_iov = iov;
  212.     h.msg_iovlen = 1;
  213.     h.msg_accrights = ((caddr_t)(&fd));
  214.     h.msg_accrightslen = (sizeof fd);
  215.     ans = recvmsg(XR_socket0FD, &h, 0); /* XR_ProtectSysCall not required. */
  216.     if( ans < 0 ) {
  217.         int theError = errno;
  218. #       ifdef UNDEFINED
  219.         XR_ConsoleMsg("%? errno %d\n", theError);
  220.             XR_Panic("MMapIOPRecvDescriptor 0");
  221. #       endif
  222.     return (-theError);
  223.     }
  224.     if( fd < 0 ) {
  225. #       ifdef UNDEFINED
  226.             XR_Panic("MMapIOPRecvDescriptor 0");
  227. #       endif
  228.         return (-EINVAL);
  229.     }
  230.     return fd;
  231. }
  232.  
  233.  
  234. void
  235. XR_MMapIOPOrderProc (iopo)
  236.     XR_IOPOrder iopo;
  237. {
  238.     int ans, d;
  239.     XR_MMArgs mma = ((XR_MMArgs)(iopo->iopo_mma));
  240.  
  241.     d = XR_MMapIOPRecvDescriptor();
  242.     if( d >= 0 ) {
  243.         ans = XR_DoMMapProc (mma, d);
  244.         (void) close(d);
  245.     } else {
  246.         ans = d;
  247.     }
  248.     if( (ans == 0) && (XR_iope->iope_index == 0) ) {
  249.         ans = XR_MemIOPIssueVPOrder(mma, XR_MMapVPOrderProc);
  250.     }
  251.     iopo->iopo_results[0] = ((unsigned)(ans));
  252.     XR_UIONotifyIOPODone(iopo);
  253. }
  254.  
  255.  
  256.  
  257. /* MMap Exported to UIO.h */
  258.  
  259.  
  260. static void
  261. XR_MMapSendDescriptorLocalProc(order, iope)
  262.     XR_IOPOrder order;
  263.     XR_IOPE iope;
  264. {
  265.     XR_MMArgs mma;
  266.     int fd;
  267.     struct iovec iov[1];
  268.     struct msghdr h;
  269.     int ans;
  270.     int buf;    /* Dummy to circumvent recvmsg bug */
  271.  
  272.     mma = ((XR_MMArgs)(order->iopo_mma));
  273.     fd = mma->mma_fd;
  274.     h.msg_name = NIL;
  275.     h.msg_namelen = 0;
  276.     iov[0].iov_base = (caddr_t)(&buf);
  277.     iov[0].iov_len = sizeof (int);
  278.     h.msg_iov = iov; /* not really used ... */
  279.     h.msg_iovlen = 1;
  280.     h.msg_accrights = ((caddr_t)(&fd));
  281.     h.msg_accrightslen = (sizeof fd);
  282.     ans = sendmsg( XR_socket1FD, &h, 0 );
  283.     if( ans < 0 ) {
  284.         int theError = XR_GetErrno();
  285.         XR_ConsoleMsg( "%? sendmsg errno %d socket1FD %d fd %d\n",
  286.                 theError, XR_socket1FD, fd );
  287.         XR_Panic("MMapSendDescriptorLocalProc 0");
  288.     }
  289. }
  290.  
  291.  
  292. static XR_FDE_FDC_WORKER(XR_MMapWorker)
  293. {
  294.     XR_MMArgs mma = ((XR_MMArgs)(x1));
  295.     struct XR_IOPOrderRep iopo;
  296.     XR_IOPOResult iopoResult;
  297.     int ans;
  298.  
  299.     mma->mma_fd = fdc->fdc_index;
  300.     iopo.iopo_mma = ((unsigned)(mma));
  301.     iopoResult = XR_IssueIOPOrders(
  302.     /*order*/    &iopo,
  303.     /*proc*/    XR_MMapIOPOrderProc,
  304.     /*localProc*/    XR_MMapSendDescriptorLocalProc
  305.     );
  306.     if( iopoResult != XR_IOPO_RESULT_OK ) {
  307.         XR_Panic("MMapWorker 0");
  308.     }
  309.     ans = ((int)(iopo.iopo_results[0]));
  310.     if( ans < 0 ) {
  311.         XR_SetErrno(-ans);
  312.         return (-1);
  313.     }
  314.     return ans;
  315. }
  316.  
  317.  
  318. int
  319. XR_MMap(addr, len, prot, flags, fildes, off)
  320.     XR_Pointer addr;
  321.     unsigned len;
  322.     int prot;
  323.     int flags;
  324.     XR_Fildes fildes;
  325.     unsigned off;
  326. {
  327.     struct XR_MMArgsRep mma;
  328.     int ans, savedErrno;
  329.  
  330.     if( fildes == XR_nullFildes ) {
  331.         XR_SetErrno(EBADF);
  332.         return (-1);
  333.     }
  334.  
  335.     if( ((flags & (MAP_SHARED|MAP_FIXED)) != (MAP_SHARED|MAP_FIXED))
  336.             || (!XR_ValidAddressRangeForMMap(addr, len)) ) {
  337.         XR_SetErrno(EINVAL);
  338.         return(-1);
  339.     }
  340.  
  341.     (void)bzero( &mma, (sizeof mma) );
  342.     mma.mma_addr = addr;
  343.     mma.mma_len = len;
  344.     mma.mma_prot = prot;
  345.     mma.mma_flags = flags;
  346.     mma.mma_fd = ((unsigned)(-1));    /* filled in later from fdc */
  347.     mma.mma_off = off;
  348.  
  349.     ans = XR_UIODoWithFDEAndFDC(
  350.     /*fildes*/        fildes,
  351.     /*waitReadyProc*/     NIL,
  352.     /*proc*/        XR_MMapWorker,
  353.     /*x1*/            ((unsigned)(&mma)),
  354.     /*x2*/            0
  355.     );
  356.     if( ans != 0 ) {
  357.         savedErrno = XR_GetErrno();
  358.         (void) XR_MUnmap(addr, len);
  359.         XR_SetErrno(savedErrno);
  360.         return (-1);
  361.     }
  362.     return addr;
  363. }
  364.  
  365.  
  366. /* munmap primitives */
  367.  
  368.  
  369. #define XR_ValidAddressRangeForMUnmap(addr,len) \
  370.     XR_ValidAddressRangeForMMap((addr), (len))
  371.  
  372.  
  373. static int /* -errno */
  374. XR_DoMUnmapProc (mma)
  375.     XR_MMArgs mma;
  376. {
  377.     int munmapAns;
  378.     int theResult = 0;
  379.  
  380. #if DEBUG_MMAP
  381.     XR_ConsoleMsg("MUnmapVPOrder addr 0x%x len %d\n",
  382.         mma->mma_addr, mma->mma_len);
  383. #endif
  384.  
  385.     munmapAns = munmap(
  386.         mma->mma_addr,
  387.         mma->mma_len
  388.     );
  389.     if( munmapAns != 0 ) {
  390.         theResult = -errno;
  391. #       if DEBUG_MMAP
  392.             XR_ConsoleMsg("%? DoMUnmapProc ans 0x%x errno %d\n",
  393.                 munmapAns, -theResult);
  394.             XR_ConsoleMsg("addr 0x%x len %d\n", mma->mma_addr, mma->mma_len);
  395. #       endif
  396.     }
  397.     mma->mma_results[ResultIndex()] = theResult;
  398.     return theResult;
  399. }
  400.  
  401.  
  402. /* MUnmap VP Procs */
  403.  
  404. void
  405. XR_MUnmapVPOrderProc (vpo)
  406.     XR_VPOrder vpo;
  407. {
  408.     XR_MMArgs mma = (XR_MMArgs)(vpo->vpo_mma);
  409.  
  410.     if( XR_vpe == NIL )
  411.         XR_Panic("MUnmapVPOrderProc 0");
  412.     (void) XR_DoMUnmapProc(mma);
  413. }
  414.  
  415.  
  416. /* MUnmap IOP Procs */
  417.  
  418.  
  419. void
  420. XR_MUnmapIOPOrderProc (iopo)
  421.     XR_IOPOrder iopo;
  422. {
  423.     int ans, vpAns;
  424.     XR_MMArgs mma = ((XR_MMArgs)(iopo->iopo_mma));
  425.  
  426.     ans = XR_DoMUnmapProc(mma);
  427.     vpAns = ( (XR_iope->iope_index == 0)
  428.             ? XR_MemIOPIssueVPOrder(mma, XR_MUnmapVPOrderProc)
  429.             : 0 );
  430.     iopo->iopo_results[0] = ( (unsigned)((ans < 0) ? ans : vpAns) );
  431.     XR_UIONotifyIOPODone(iopo);
  432. }
  433.  
  434.  
  435. /* MUnmap Exported to UIO.h */
  436.  
  437.  
  438. int
  439. XR_MUnmap(addr, len)
  440.     XR_Pointer addr;
  441.     unsigned len;
  442. {
  443.     struct XR_MMArgsRep mma;
  444.     struct XR_IOPOrderRep iopo;
  445.     XR_IOPOResult iopoResult;
  446.     int ans;
  447.  
  448.     if( !XR_ValidAddressRangeForMUnmap(addr, len) ) {
  449.         XR_SetErrno(EINVAL);
  450.         return(-1);
  451.     }
  452.  
  453.     (void)bzero( &mma, (sizeof mma) );
  454.     mma.mma_addr = addr;
  455.     mma.mma_len = len;
  456.     iopo.iopo_mma = ((unsigned)(&mma));
  457.     iopoResult = XR_IssueIOPOrders(
  458.     /*order*/    &iopo,
  459.     /*proc*/    XR_MUnmapIOPOrderProc,
  460.     /*localProc*/    NIL
  461.     );
  462.     if( iopoResult != XR_IOPO_RESULT_OK ) {
  463.         XR_Panic("XR_MUnmap 0");
  464.     }
  465.     ans = ((int)(iopo.iopo_results[0]));
  466.     if( ans < 0 ) {
  467.         XR_SetErrno(-ans);
  468.         return (-1);
  469.     }
  470.     return 0;
  471. }
  472.  
  473.  
  474. /* mprotect primitives */
  475.  
  476.  
  477. static bool
  478. XR_ValidAddressRangeForMProtect(addr, len)
  479.     XR_Pointer addr;
  480.     unsigned len;
  481. {
  482.     XR_Seg heapSeg;
  483.     bool XR_OverlapsVDProtected(/* XR_Pointer addr, unsigned len */);
  484.  
  485.     if( addr != XR_ComputeAddress(addr, 0, XR_ROUND_DOWN) ) {
  486.         /* not page-aligned */
  487.         return FALSE;
  488.     }
  489.     /*
  490.      * Make sure it's not in the heap or adjacenr areas; the collector has
  491.      * exclusive rights there.
  492.      */
  493.     return ( ! XR_OverlapsVDProtected(addr, len) );
  494. }
  495.  
  496.  
  497. static int /* -errno */
  498. XR_DoMProtectProc (mma)
  499.     XR_MMArgs mma;
  500. {
  501.     int mprotectAns;
  502.     int theResult = 0;
  503.  
  504. #if DEBUG_MMAP
  505.     XR_ConsoleMsg("DoMProtectProc addr 0x%x len %d prot 0x%x\n",
  506.         mma->mma_addr, mma->mma_len, mma->mma_prot);
  507. #endif
  508.  
  509.     mprotectAns = mprotect(
  510.         mma->mma_addr,
  511.         mma->mma_len,
  512.         mma->mma_prot
  513.     );
  514.     if( mprotectAns != 0 ) {
  515.         theResult = -errno;
  516. #       if DEBUG_MMAP
  517.             XR_ConsoleMsg("%? DoMProtectProc mprotect ans 0x%x errno %d\n",
  518.                 mprotectAns, -theResult);
  519.             XR_ConsoleMsg("addr 0x%x len %d prot 0x%x\n",
  520.                 mma->mma_addr, mma->mma_len, mma->mma_prot);
  521. #       endif
  522.     }
  523.     mma->mma_results[ResultIndex()] = theResult;
  524.     return theResult;
  525. }
  526.  
  527. /* MProtect VP Procs */
  528.  
  529. void
  530. XR_MProtectVPOrderProc (vpo)
  531.     XR_VPOrder vpo;
  532. {
  533.     XR_MMArgs mma = (XR_MMArgs)(vpo->vpo_mma);
  534.  
  535.     if( XR_vpe == NIL )
  536.         XR_Panic("MProtectVPOrderProc 0");
  537.     (void) XR_DoMProtectProc(mma);
  538. }
  539.  
  540.  
  541.  
  542. /* MProtect IOP Procs */
  543.  
  544.  
  545.  
  546. static void
  547. XR_MProtectIOPOrderProc (iopo)
  548.     XR_IOPOrder iopo;
  549. {
  550.     int ans, vpAns;
  551.     XR_MMArgs mma = ((XR_MMArgs)(iopo->iopo_mma));
  552.  
  553.     if (mma -> mma_include_iops) {
  554.         ans = XR_DoMProtectProc(mma);
  555.     } else {
  556.         ans = 0;
  557.     }
  558.     vpAns = ( (XR_iope->iope_index == 0)
  559.             ? XR_MemIOPIssueVPOrder(mma, XR_MProtectVPOrderProc)
  560.             : 0 );
  561.     iopo->iopo_results[0] = ((unsigned)((ans < 0) ? ans : vpAns) );
  562.     XR_UIONotifyIOPODone(iopo);
  563. }
  564.  
  565.  
  566. /* A version of MProtect that allows heap addresses, does no checking  on  */
  567. /* on addr, and allows caller to specify whether or not IOPs are included. */
  568.  
  569. int
  570. XR_MProtect4(addr, len, prot, include_iops)
  571.     XR_Pointer addr;
  572.     unsigned len;
  573.     int prot;
  574.     bool include_iops;
  575. {
  576.     struct XR_MMArgsRep mma;
  577.     struct XR_IOPOrderRep iopo;
  578.     XR_IOPOResult iopoResult;
  579.     XR_Pri oldPri;
  580.     XR_Pri highPri = XR_PRI_SYS_EXCLUSIVE;
  581.     int ans;
  582.  
  583.     if (!include_iops && XR_sysArea->sa_numVP == 1) {
  584.       /* Just do it and don't bother the iop */
  585.         return(mprotect(addr, len, prot));
  586.     }
  587.     (void)bzero( &mma, (sizeof mma) );
  588.     mma.mma_addr = addr;
  589.     mma.mma_len = len;
  590.     mma.mma_prot = prot;
  591.     mma.mma_include_iops = include_iops;
  592.     iopo.iopo_mma = ((unsigned)(&mma));
  593.     /* Set my priority to a very high value.  Otherwise I might not get */
  594.     /* immediately notified when this finishes.  This will leave me not */
  595.     /* running, but holding IOP order locks.  This may be better done   */
  596.     /* in XR_IssueIOPOrders, but this is the case that causes problems. */
  597.     oldPri = XR_GetPriority();
  598.     XR_SchedCtl(
  599.             XR_SchedCtlWhichSelf(),
  600.             scop_setPriority,
  601.             ((unsigned long *)(&highPri))
  602.     );
  603.     if (include_iops) {
  604.       iopoResult = XR_IssueIOPOrders(
  605.     /*order*/    &iopo,
  606.     /*proc*/    XR_MProtectIOPOrderProc,
  607.     /*localProc*/    NIL
  608.       );
  609.     } else {
  610.       iopoResult = XR_IssueIOPOrder(
  611.         /*iop*/        &(XR_sysArea->sa_iope[0]),
  612.         /*order*/    &iopo,
  613.     /*proc*/    XR_MProtectIOPOrderProc,
  614.     /*cancel*/    NIL,
  615.     /*abortable*/    FALSE,
  616.     /*timeout*/    XR_WAIT_FOREVER
  617.       );
  618.     }
  619.     XR_SchedCtl(
  620.             XR_SchedCtlWhichSelf(),
  621.             scop_setPriority,
  622.             ((unsigned long *)(&oldPri))
  623.     );
  624.     if( iopoResult != XR_IOPO_RESULT_OK ) {
  625.         XR_Panic("XR_MProtect 0");
  626.     }
  627.     ans = ((int)(iopo.iopo_results[0]));
  628.     if( ans < 0 ) {
  629.         XR_SetErrno(-ans);
  630.         return (-1);
  631.     }
  632.     return 0;
  633. }
  634.  
  635.  
  636. /* MProtect Exported to UIO.h */
  637.  
  638.  
  639. int
  640. XR_MProtect(addr, len, prot)
  641.     XR_Pointer addr;
  642.     unsigned len;
  643.     int prot;
  644. {
  645.     struct XR_MMArgsRep mma;
  646.     struct XR_IOPOrderRep iopo;
  647.     XR_IOPOResult iopoResult;
  648.     int ans;
  649.  
  650.     if( !XR_ValidAddressRangeForMProtect(addr, len) ) {
  651.         XR_SetErrno(EINVAL);
  652.         return(-1);
  653.     }
  654.     return (XR_MProtect4(addr, len, prot, TRUE));
  655. }
  656.  
  657.  
  658. /*
  659.  * MCtl
  660.  */
  661.  
  662. #define mma_function    mma_prot
  663. #define mma_arg        mma_flags
  664.  
  665.  
  666. static int /* -errno */
  667. XR_DoMCtlProc (mma)
  668.     XR_MMArgs mma;
  669. {
  670.     int mctlAns;
  671.     int theResult = 0;
  672.  
  673. #if DEBUG_MMAP
  674.     XR_ConsoleMsg("DoMCtlProc addr 0x%x len %d fcn 0x%x arg 0x%x\n",
  675.         mma->mma_addr, mma->mma_len, mma->mma_function, mma->mma_arg);
  676. #endif
  677.  
  678.     mctlAns = mctl(
  679.         mma->mma_addr,
  680.         mma->mma_len,
  681.         mma->mma_function,
  682.         mma->mma_arg
  683.     );
  684.     if( mctlAns < 0 ) {
  685.         theResult = -errno;
  686. #       if DEBUG_MMAP
  687.             XR_ConsoleMsg("%? DoMCtlProc mctl ans 0x%x errno %d\n",
  688.                 mctlAns, -theResult);
  689.             XR_ConsoleMsg("addr 0x%x len %d fcn 0x%x arg 0x%x\n",
  690.                 mma->mma_addr, mma->mma_len, mma->mma_function, mma->mma_arg);
  691. #       endif
  692.     }
  693.     mma->mma_results[ResultIndex()] = theResult;
  694.     return theResult;
  695. }
  696.  
  697.  
  698. void
  699. XR_MCtlVPOrderProc (vpo)
  700.     XR_VPOrder vpo;
  701. {
  702.     XR_MMArgs mma = (XR_MMArgs)(vpo->vpo_mma);
  703.  
  704.     if( XR_vpe == NIL )
  705.         XR_Panic("MCtlVPOrderProc 0");
  706.     (void) XR_DoMCtlProc(mma);
  707. }
  708.  
  709.  
  710. static void
  711. XR_MCtlIOPOrderProc (iopo)
  712.     XR_IOPOrder iopo;
  713. {
  714.     int ans, vpAns;
  715.     XR_MMArgs mma = ((XR_MMArgs)(iopo->iopo_mma));
  716.  
  717.     if (mma -> mma_include_iops) {
  718.         ans = XR_DoMCtlProc(mma);
  719.     } else {
  720.         ans = 0;
  721.     }
  722.     vpAns = ( (XR_iope->iope_index == 0)
  723.             ? XR_MemIOPIssueVPOrder(mma, XR_MCtlVPOrderProc)
  724.             : 0 );
  725.     iopo->iopo_results[0] = ((unsigned)((ans < 0) ? ans : vpAns) );
  726.     XR_UIONotifyIOPODone(iopo);
  727. }
  728.  
  729.  
  730. int
  731. XR_MCtl5(addr, len, function, arg, include_iops)
  732.     XR_Pointer addr;
  733.     unsigned len;
  734.     int function;
  735.     XR_Pointer arg;
  736.     bool include_iops;
  737. {
  738.     struct XR_MMArgsRep mma;
  739.     struct XR_IOPOrderRep iopo;
  740.     XR_IOPOResult iopoResult;
  741.     int ans;
  742.  
  743.     (void)bzero( &mma, (sizeof mma) );
  744.     mma.mma_addr = addr;
  745.     mma.mma_len = len;
  746.     mma.mma_function = function;
  747.     mma.mma_arg = arg;
  748.     mma.mma_include_iops = include_iops;
  749.     iopo.iopo_mma = ((unsigned)(&mma));
  750.     iopoResult = XR_IssueIOPOrders(
  751.     /*order*/    &iopo,
  752.     /*proc*/    XR_MCtlIOPOrderProc,
  753.     /*localProc*/    NIL
  754.     );
  755.     if( iopoResult != XR_IOPO_RESULT_OK ) {
  756.         XR_Panic("XR_MProtect 0");
  757.     }
  758.     ans = ((int)(iopo.iopo_results[0]));
  759.     if( ans < 0 ) {
  760.         XR_SetErrno(-ans);
  761.         return (-1);
  762.     }
  763.     return 0;
  764. }
  765.  
  766.  
  767. int
  768. XR_MCtl(addr, len, function, arg)
  769.     XR_Pointer addr;
  770.     unsigned len;
  771.     int function;
  772.     XR_Pointer arg;
  773. {
  774.     return (XR_MCtl5(addr, len, function, arg, TRUE));
  775. }
  776.  
  777.  
  778. #undef mma_function
  779. #undef mma_arg
  780.  
  781.  
  782. /*
  783.  * int msync(XR_Pointer addr, int len, int flags)
  784.  */
  785.  
  786. int
  787. XR_MSync(addr, len, flags)
  788.     XR_Pointer addr;
  789.     int len;
  790.     int flags;
  791. {
  792.     return msync(addr, len, flags);
  793. }
  794.